#include "stm32f10x.h"

uint32_t MyDMA_Size;

void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size) {
    MyDMA_Size = Size;
    // 1. RCC
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    // 2. DMA初始化
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA; // 外设站点的起始地址
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设站点的数据宽度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; // 外设站点的是否自增
    DMA_InitStructure.DMA_MemoryBaseAddr = AddrB; // 存储器的外设站点的起始地址
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 存储器的外设站点的数据宽度
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 存储器的外设站点的是否自增
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 方向(A => B)
    DMA_InitStructure.DMA_BufferSize = Size; // 缓存区大小（传输计数器）
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 传输模式（是否自动重装）
    DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; // 软件、硬件触发
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 优先级
    DMA_Init(DMA1_Channel1, &DMA_InitStructure); // 软件到软件，所以 Channel 可以随意
    // 3. 开关控制
    DMA_Cmd(DMA1_Channel1, DISABLE);
}

void MyDMA_Transfer(void) {
    DMA_SetCurrDataCounter(DMA1_Channel1, MyDMA_Size);
    DMA_Cmd(DMA1_Channel1, ENABLE);
    // 等待转运完成
    while (!DMA_GetFlagStatus(DMA1_FLAG_TC1));
    DMA_ClearFlag(DMA1_FLAG_TC1);
    DMA_Cmd(DMA1_Channel1, DISABLE);
}
